package doc2db.interfaces.action.save;

import doc2db.Keey;
import doc2db.fileWorker.FileIO;
import doc2db.interfaces.mainWindow.MyJEditorPane;
import java.io.File;
import java.util.ArrayList;

/**
 *
 * @author yura
 */
public class SaveTxt implements Saver{
    /** Edit panel whith date */
    private MyJEditorPane medit ;

    /** Text of error if it hapen */
    private String error = "ancnown";

    /**
     * this.medit = medit;
     * @param medit edit panel whith date
     */
    public SaveTxt(MyJEditorPane medit) {
        this.medit = medit;
    }

    @Override
    public String err(){
        return error;
    }

    /**
     *  Edit panel whith date
     * @return Edit panel whith date
     */
    public MyJEditorPane getMedit() {
        return medit;
    }

    /**
     *  Edit panel whith date
     * @param medit Edit panel whith date
     */
    public void setMedit(MyJEditorPane medit) {
        this.medit = medit;
    }


    @Override
    public boolean save (String fname){
        return saveTxt(fname);
    }

    /**
     * Save date from medit in text format
     * @param fname name of file
     * @return true  if it saved and false in another way,
     * error message can get to call method getError();
     */
    public boolean saveTxt (String fname){
        /* имя файла для сохранения */
        String mfname;

        String[][] tableData = medit.table;

        if (new File(fname).exists()){
            mfname = "" + fname;
        } else if (fname.endsWith(".txt") | fname.endsWith(".TXT")) {
            mfname = "" + fname;
        } else {
            mfname = fname + ".txt";
        }

        StringBuilder sb = getTextData(tableData);

        boolean ret = FileIO.createFile(sb.toString(), mfname);
        if (! ret){
            error = "file IO exception";
        }
        return ret;
    }

    /**
     *  Represent data from array 
     * @param tableData
     * @return
     */
    public StringBuilder getTextData(String[][] tableData) {
        /**/
        StringBuilder sb = new StringBuilder();
        /* максимальная длина строки в каждом столбце */
        int[] lens = new int[tableData[0].length];
        /* ялвляется ли заданная строка много строковой */
        boolean[] mulline = new boolean[tableData.length];
        for (int i = 0; i < lens.length; i++) {
            lens[i] = 2;
        }
        for (int i = 0; i < mulline.length; i++) {
            mulline[i] = false;
        }
        for (int i = 0; i < tableData.length; i++) {
            for (int j = 0; j < tableData[0].length; j++) {
                if (tableData[i][j].indexOf('\n') >= 0) {
                    //split("\n").length > 0){
                    mulline[i] = true;
                    break;
                }
            }
        }
        for (int i = 0; i < tableData.length; i++) {
            for (int j = 0; j < tableData[0].length; j++) {
                for (String s : tableData[i][j].split("\n")) {
                    if (lens[j] < s.length()) {
                        lens[j] = s.length();
                    }
                }
            }
        }
        for (int c = 0; c < tableData.length; c++) {
            String[] ss = tableData[c];
            if (Keey.debug) {
                for (int i = 0; i < ss.length; i++) {
                    sb.append(ss[i].replaceAll("\n", "\\\\n")
                            .replaceAll("\t", "\\\\t").replaceAll("\r", "\\\\r"));
                    if ((i + 1) < ss.length) {
                        sb.append('\t');
                    }
                }
            } else {
                if (mulline[c]) {
                    sb.append(addMullLine(ss, lens));
                } else {
                    for (int i = 0; i < ss.length; i++) {
                        sb.append("" + ss[i]).append(space(' ', lens[i] - ss[i].length()));
                        if ((i + 1) < ss.length) {
                            sb.append(" | ");
                        }
                    }
                }
            }
            sb.append("\n");
            if (!Keey.debug) {
                for (int i = 0; i < lens.length; i++) {
                    int k = i > 0 ? 2 : 1;
                    sb.append(space('-', lens[i] + k));
                    if ((i + 1) < lens.length) {
                        if ((c + 1) < tableData.length) {
                            sb.append('+');
                        } else {
                            sb.append('-');
                        }
                    }
                }
                sb.append("\n");
            }
        }
        return sb;
    }

    /**
     * Еслиу в данной строке ячейки содержат ререносы строки,
     * то метод обработает это
     * @param cols масив значений ячеек
     * @param lens абсолютные длины ячеек
     * @return строку текст для добавления к общему буферу
     */
    private String addMullLine(String [] cols, int [] lens){
        StringBuilder sb = new StringBuilder();
        String arr [][] = splitArr(cols, "\n");
        int size = arr[0].length;
        for (String[] s : arr) {
            if (size < s.length){
                size = s.length;
            }
        }

        for (int i = 0; i < size; i++) {
            for (int j = 0; j < arr.length; j++) {
                if (arr[j].length > i){
                    sb.append("" + arr[j][i])
                            .append(space(' ', lens[j] - arr[j][i].length()));
                } else {
                    sb.append(space(' ', lens[j]));
                }
                if ((j + 1) < arr.length) {
                    sb.append(" | ");
                }
            }
            if ((i + 1) < size) {
                sb.append("\n");
            }
        }
        return sb.toString();
    }


    /**
     * создаёт строку состоящую из "ch" продублированных "kol" раз
     * @param ch  символ для дублирования
     * @param kol количество дублирований
     * @return строку текста
     */
    public static String space (char ch, int kol){
        if ( kol < 1 )
            return "";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < kol; i++) {
            sb.append(ch);
        }
        return sb.toString();
    }

    /**
     * Разбивае масив строк на двойной масив строк,
     * разбивая каждую строку в массиве заданой лексемой
     * @param arr масив строк для разбиения
     * @param splitChar строка (символ) для диления (разбиения) строк
     * @return двойной масив строк
     */
    public static String [][] splitArr(String arr[], String splitChar){
        String [][] ret = new String[arr.length][];
        for (int i = 0; i < ret.length; i++) {
            ret[i] = arr[i].split(splitChar);
        }
        return ret;
    }

}
